/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Server;
import java.net.*;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

/**
 * The Server class is the main class of server application.
 * 
 * @author hartingm
 */
public class Server {

   /********************
    * Attributes
    ********************/
	private ArrayList <ServerThread> clientList;
        
	/**
	 * Build a new server.
	 * Port < 1023.
	 * @param args server listening port
	 */
	public Server(String[] args) {
		try {
			Date date = new Date();
			SimpleDateFormat format = new SimpleDateFormat("EEE d MMM yyyy HH:mm:ss z");
			System.out.println("\nStarting Project Chat Server 1.0 at " + format.format(date) +"\n");
			
			int port; //server port number
			Integer threadName = 0; 

            if (args.length != 1 || Integer.parseInt(args[0])<=1023) { // port should not be less than 1023
				port = 10010;
                System.out.println("Server: Set port number to default value (10010).");
             }
             else {
                port = Integer.parseInt(args[0]);
                System.out.println("Server: Set port number to " + port + ".");
             }
                        
             System.out.println("Server: Creating empty client list.");
             clientList = new ArrayList<ServerThread>();
                        
             System.out.println("Server: Creating listening socket.");
			 ServerSocket listenSocket = new ServerSocket(port); //listening socket
			
			 for(;;) {
				System.out.println("Server: Waiting a connection ("+clientList.size()+" connected).");
                                
				Socket transfertSocket = listenSocket.accept();
                System.out.println("Server: Connection from ip: "+transfertSocket.getInetAddress().getHostAddress() + ":" +transfertSocket.getPort());
                System.out.println("Server: Transfert socket created..");
				
                System.out.println("Server: Creating client thread.");
				ServerThread client = new ServerThread("Thread"+threadName.toString(), this, transfertSocket);
				threadName ++;
				Thread.sleep(10);
			}
		}
		catch(Exception e){
			System.out.println("Server: Error class Server ("+e.toString()+").");
		}
	}

	/**
	 * The main method
	 * @param args the server listening port
	 */
	public static void main(String[] args) {
		Server server = new Server(args);
	}
	/**
     * Return the number of connected clients.
     * @return the number of connected clients
     */
    public synchronized int countClient() {
        return clientList.size();
    }

	/**
	 * Return the client list.
	 * @return client list
	 */
	public synchronized ArrayList<ServerThread> getClientList() {
		return clientList;
	}
	
    /**
	 * Return a server thread corresponding to a nickname.
	 * @param nickname
	 * @return the ServerThread corresponding to nickname, null if it does not exist
	 */
	public synchronized ServerThread getClient(String nickname) {
		ServerThread searched = null;
		for (int i=0; i<clientList.size(); i++) {
			ServerThread client = clientList.get(i);
			if (client.getNickname().equals(nickname))
				searched = client;
		}
		return searched;
	}//end getClient

	/**
	 * Add a client to the connected list.
	 * @param serverThread the client to add
	 * @return true if client was added, false if client was already connected
	 */
    public synchronized boolean addClient(ServerThread serverThread) {
        if (getClient(serverThread.getNickname()) == null) { //this client is not connected
			clientList.add(serverThread);
            return true;
        }
        else { //the client is already connected
            System.out.println("Server: Client already connected: connection denied.");
            return false;
        }
    }//end addClient

	/**
	 * Remove a client from the connected list.
	 * @param serverThread the client to remove
	 * @return true if client has been removed, false if he was not in the list
	 */
	public synchronized boolean removeClient(ServerThread serverThread) {
		//delete the client to the clientList and return true
		//if client is not in the list the method return false
		
		if (getClient(serverThread.getNickname()) != null) { //the client is in the list (connected)
			clientList.remove(serverThread);
			return true;
		}
		else { //the client is not connected
			System.out.println("Server: Unable to diconnect client: client not connected.");
			return false;
		}
	}//end removeClient
	
}//end Server class
